/**
 ******************************************************************************
 * @file    Project/STM32F10x_StdPeriph_Template/main.c
 * @author  MCD Application Team
 * @version V3.3.0
 * @date    04/16/2010
 * @brief   Main program body
 ******************************************************************************
 * @copy
 *
 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
 * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
 * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
 * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
 *
 * <h2><center>&copy; COPYRIGHT 2010 STMicroelectronics</center></h2>
 */

/* Includes ------------------------------------------------------------------*/
#include "b_os.h"
#include "stm32f10x.h"

/** @addtogroup Template_Project
 * @{
 */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define _24CXX_TEST_ENABLE (1)
#define _DS18B20_TEST_ENABLE (1)
#define _MCUFLASH_TEST_ENABLE (1)
#define _OLED_TEST_ENABLE (0)
#define _SDCARD_TEST_ENABLE (1)
#define _SPIFLASH_TEST_ENABLE (0)
#define _SSD1289_TEST_ENABLE (1)
#define _XPT2046_TEST_ENABLE (1)
/* Private macro -------------------------------------------------------------*/
static void SystickInit()
{
    /* Setup SysTick Timer  */
    if (SysTick_Config(SystemCoreClock / _TICK_FRQ_HZ))
    {
        /* Capture error */
        while (1)
            ;
    }
    /* Configure the SysTick handler priority */
    NVIC_SetPriority(SysTick_IRQn, 0x0);
}

static void ClockInit()
{
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC |
                               RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_SPI1 |
                               RCC_APB2Periph_USART1 | RCC_APB2Periph_AFIO,
                           ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);
}

static void GpioInit()
{
    GPIO_InitTypeDef GPIO_InitStructure;
    /**
     * \brief UART1 GPIO INIT PA9 PA10
     */
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* Configure USART Rx as input floating */
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_10;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /**
     * \brief SPI1 GPIO INIT PA5-CLK PA6-MISO PA7-MOSI PB9-CS
     */
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    GPIO_SetBits(GPIOB, GPIO_Pin_9);

    // SPI3--LCD
    GPIO_PinRemapConfig(GPIO_Remap_SPI3, ENABLE);
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOC, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
    GPIO_Init(GPIOC, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
    GPIO_Init(GPIOC, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
    GPIO_SetBits(GPIOC, GPIO_Pin_9);

    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
    GPIO_SetBits(GPIOC, GPIO_Pin_8);

    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_13 | GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOD, &GPIO_InitStructure);
    GPIO_SetBits(GPIOD, GPIO_Pin_13);
    GPIO_SetBits(GPIOD, GPIO_Pin_15);

    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_14;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    GPIO_SetBits(GPIOB, GPIO_Pin_14);

    /**
     * IIC  PB6-SCL   PB7-SDA
     */
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_6;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    /**
     * IIC  PB0-SCL   PB1-SDA
     */
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_4;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOD, &GPIO_InitStructure);
    GPIO_SetBits(GPIOD, GPIO_Pin_11);

    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_All;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOE, &GPIO_InitStructure);
}

static void UartInit()
{
    NVIC_InitTypeDef  NVIC_InitStruct;
    USART_InitTypeDef USART_InitStructure;
    USART_InitStructure.USART_BaudRate            = 115200;
    USART_InitStructure.USART_WordLength          = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits            = USART_StopBits_1;
    USART_InitStructure.USART_Parity              = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode                = USART_Mode_Rx | USART_Mode_Tx;
    USART_Init(USART1, &USART_InitStructure);

    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

    NVIC_InitStruct.NVIC_IRQChannel                   = USART1_IRQn;
    NVIC_InitStruct.NVIC_IRQChannelCmd                = ENABLE;
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStruct.NVIC_IRQChannelSubPriority        = 0;
    NVIC_Init(&NVIC_InitStruct);

    USART_Cmd(USART1, ENABLE);
}

static void SpiInit()
{
    SPI_InitTypeDef SPI_InitStructure;
    SPI_InitStructure.SPI_Direction         = SPI_Direction_2Lines_FullDuplex;
    SPI_InitStructure.SPI_Mode              = SPI_Mode_Master;
    SPI_InitStructure.SPI_DataSize          = SPI_DataSize_8b;
    SPI_InitStructure.SPI_CPOL              = SPI_CPOL_High;
    SPI_InitStructure.SPI_CPHA              = SPI_CPHA_2Edge;
    SPI_InitStructure.SPI_NSS               = SPI_NSS_Soft;
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
    SPI_InitStructure.SPI_FirstBit          = SPI_FirstBit_MSB;
    SPI_InitStructure.SPI_CRCPolynomial     = 7;
    SPI_Init(SPI1, &SPI_InitStructure);
    SPI_Cmd(SPI1, ENABLE);

    SPI_InitStructure.SPI_Direction         = SPI_Direction_2Lines_FullDuplex;
    SPI_InitStructure.SPI_Mode              = SPI_Mode_Master;
    SPI_InitStructure.SPI_DataSize          = SPI_DataSize_8b;
    SPI_InitStructure.SPI_CPOL              = SPI_CPOL_Low;
    SPI_InitStructure.SPI_CPHA              = SPI_CPHA_1Edge;
    SPI_InitStructure.SPI_NSS               = SPI_NSS_Soft;
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;
    SPI_InitStructure.SPI_FirstBit          = SPI_FirstBit_MSB;
    SPI_InitStructure.SPI_CRCPolynomial     = 10;
    SPI_Init(SPI3, &SPI_InitStructure);
    SPI_Cmd(SPI3, ENABLE);
}

/****************************BabyOS 测试代码*************************************/
static void _24C02Test()
{
#if _24CXX_TEST_ENABLE
    int      fd  = -1;
    uint32_t tmp = 0;
    fd           = bOpen(_24C02, BCORE_FLAG_RW);
    if (fd < 0)
    {
        return;
    }

    bLseek(fd, 0);
    bRead(fd, (uint8_t *)&tmp, sizeof(uint32_t));
    b_log("reboot count:%d\r\n", tmp);

    tmp += 1;

    bLseek(fd, 0);
    bWrite(fd, (uint8_t *)&tmp, sizeof(uint32_t));
    bClose(fd);
#endif
}

#if _DS18B20_TEST_ENABLE
static void _CmdTempHandler(char argc, char *argv)
{
    int        fd = -1;
    bTempVal_t tmp;
    if (argc == 2)
    {
        if (strcmp("-s", &argv[argv[1]]) == 0)
        {
            fd = bOpen(DS18B20, BCORE_FLAG_RW);
            bCtl(fd, bCMD_SENSOR_START, NULL);
            bClose(fd);
        }
    }
    else if (argc == 1)
    {
        fd = bOpen(DS18B20, BCORE_FLAG_RW);
        bRead(fd, (uint8_t *)&tmp, sizeof(bTempVal_t));
        b_log("r:%d\r\n", tmp.tempx100);
        bClose(fd);
    }
}
bSHELL_REG_INSTANCE("temp", _CmdTempHandler);
#endif

#if _MCUFLASH_TEST_ENABLE || _SPIFLASH_TEST_ENABLE
static void _CmdKVHandler(char argc, char *argv)
{
    uint8_t table[12] = "null";
    if (argc == 3)
    {
        bKV_Set(&argv[argv[1]], (uint8_t *)&argv[argv[2]], strlen(&argv[argv[2]]));
        b_log("%s %s %d\r\n", &argv[argv[1]], &argv[argv[2]], strlen(&argv[argv[2]]));
    }
    else
    {
        bKV_Get(&argv[argv[1]], table);
        b_log("%s\r\n", table);
    }
}
bSHELL_REG_INSTANCE("kv", _CmdKVHandler);
#endif

static void _XPT2046Test()
{
#if _XPT2046_TEST_ENABLE
    int                  fd       = -1;
    static bTouchAdVal_t save_tmp = {0, 0};
    bTouchAdVal_t        tmp;
    fd = bOpen(XPT2046, BCORE_FLAG_R);
    if (fd < 0)
    {
        return;
    }
    bRead(fd, (uint8_t *)&tmp, sizeof(bTouchAdVal_t));
    if ((tmp.x_ad + 500) < save_tmp.x_ad || (save_tmp.x_ad + 500) < tmp.x_ad)
    {
        b_log("x:%d y:%d\r\n", tmp.x_ad, tmp.y_ad);
        save_tmp.x_ad = tmp.x_ad;
        save_tmp.y_ad = tmp.y_ad;
    }
    bClose(fd);
#endif
}

#if _SSD1289_TEST_ENABLE || _OLED_TEST_ENABLE
static void _CmdShowHandler(char argc, char *argv)
{
    if (argc == 2)
    {
        UG_PutString(0, 0, (char *)&argv[argv[1]]);
    }
}

bSHELL_REG_INSTANCE("show", _CmdShowHandler);
#endif
/********************************************************************************/
/**
 * @brief  Main program.
 * @param  None
 * @retval None
 */
int main()
{
    ClockInit();
    SystickInit();
    GpioInit();
    UartInit();
    SpiInit();
    bInit();
#if _MCUFLASH_TEST_ENABLE
    bKV_Init(MCUFLASH, 100 * 1024, 4 * 2048, 2048);
#elif _MCUFLASH_TEST_ENABLE
    bKV_Init(SPIFLASH, 100 * 1024, 4 * 4096, 4096);
#endif
#if _SSD1289_TEST_ENABLE || _OLED_TEST_ENABLE
    bGUI_Init(SSD1289, NULL);
    UG_FillScreen(C_WHITE);
    bShellInit();
#endif
#if _SDCARD_TEST_ENABLE
    bFS_Init();
    bFS_Test();
#endif
    _24C02Test();
    while (1)
    {
        bExec();
        BOS_PERIODIC_TASK(_XPT2046Test, 1000);
    }
}

void SysTick_Handler()
{
    bHalIncSysTick();
}

void USART1_IRQHandler()
{
    uint8_t uart_dat = 0;
    if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
    {
        USART_ClearITPendingBit(USART1, USART_IT_RXNE);
        uart_dat = USART_ReceiveData(USART1);
        bShellParse(&uart_dat, 1);
    }
}

#ifdef USE_FULL_ASSERT

/**
 * @brief  Reports the name of the source file and the source line number
 *   where the assert_param error has occurred.
 * @param  file: pointer to the source file name
 * @param  line: assert_param error line source number
 * @retval None
 */
void assert_failed(uint8_t *file, uint32_t line)
{
    /* User can add his own implementation to report the file name and line number,
       ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

    /* Infinite loop */
    while (1)
    {
    }
}
#endif
/**
 * @}
 */

/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
